package com.young.ums.service.impl;

import com.young.common.core.cache.ICacheClient;
import com.young.common.util.StringUtils;
import com.young.interfaces.log.annotation.Log;
import com.young.ums.model.Dept;
import com.young.ums.model.Role;
import com.young.ums.model.User;
import com.young.ums.model.enums.EDeptTypeEnum;
import com.young.ums.service.*;
import com.young.ums.util.AuthHelper;
import com.young.ums.util.UmsConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 树查询服务
 *
 * @author wangjy
 * @date 2021/10/02 17:26:43
 */
@Service
public class UmsTreeServiceImpl implements IUmsTreeService {

    private static final Logger logger = LoggerFactory.getLogger(UmsTreeServiceImpl.class);

    /**
     * 单位服务
     */
    @Resource(name="deptService")
    IDeptService deptService;
    /**
     * 角色服务
     */
    @Resource(name="roleService")
    IRoleService roleService;
    /**
     * 角色单位服务
     */
    @Resource
    IRoleDeptService roleDeptService;
    /**
     * 用户服务
     */
    @Resource(name="userService")
    IUserService userService;
    /**
     * 数据权限
     */
    @Resource
    IDataAuthService dataAuthService;

    /**
     * 查询单位树
     *
     * @param dept   查询参数
     * @param rootId 树的根节点, 根单位
     * @return 单位树
     */
    @Log("查询单位树")
    @Override
    public List<Dept> getCompanyTree(Dept dept, String rootId) {
        if (StringUtils.isNotBlank(rootId)) {
            //关闭数据权限
            dept.setEnableAuth(false);
            Dept root = deptService.get(rootId);
            if (root == null) {
                logger.info("[查询单位树] 不存在根节点={},直接返回", rootId);
                //若根节点不存在,则直接返回
                return null;
            }
            //设置管理范围为指定根节点
            dept.addManageRange(root);
            logger.info("[查询单位树] 根节点={}", rootId);
        } else {
            //权限启用参数没有传时默认启用权限设置
            AuthHelper.setAuthWhenEnableAuthIsNull(dept);
        }
        //单位查询
        dept.setType(EDeptTypeEnum.COMPANY.type);
        return deptService.getListAsTree(dept);
    }

    /**
     * 查询组织机构树
     *
     * @param dept     查询参数
     * @return 组织机构树
     */
    @Log("查询组织机构树")
    @Override
    public List<Dept> getDeptTree(Dept dept) {
        return deptService.getListAsTree(dept);
    }

    /**
     * 查询角色树
     *
     * @param dept 查询参数
     * @return
     */
    @Log("获取单位角色树")
    @Override
    public List<Dept> getRoleTree(Dept dept) {
        //单位列表
        List<Dept> list = deptService.getListAsTree(dept);
        if (list == null || list.size() == 0){
            return null;
        }

        //查询角色列表
        Role role = new Role();
        AuthHelper.setAuthWhenEnableAuthIsNull(role);//启用数据权限
        List<Role> roleList = roleService.getList(role);

        //将单位列表和角色列表关联起来
        if (roleList != null && roleList.size() > 0){
            //list转map,优化后续的查询性能
            Map<String, Dept> deptMap = new HashMap<String, Dept>(list.size());
            for (Dept dept1 : list){
                deptMap.put(dept1.getId(), dept1);
            }

            for (Role role1 : roleList){
                String companyId = role1.getCompanyId();//该角色所属的单位编号
                Dept dept1 = deptMap.get(companyId);//从map中找到对应的单位
                if (dept1 == null){
                    logger.warn("[查询单位角色树] 角色[{}]的所属单位[{}]在查询到的单位集合中匹配不到对应单位", role1.getId(), role1.getCompanyId());
                    continue;
                }
                if (dept1.getRoleList() == null){
                    dept1.setRoleList(new ArrayList<Role>());
                }
                dept1.getRoleList().add(role1);
            }
        }
        return list;
    }

    /**
     * 查询公共的角色树
     *
     * @param dept 查询参数
     * @return 公共的单位角色树
     */
    @Log("查询公共的角色树")
    @Override
    public List<Dept> getCommonRoleTree(Dept dept) {
        List<Dept> list = new ArrayList<Dept>();
        //查询单位管理权限
        List<Dept> companyList = dataAuthService.getManageRangeCompany(dept.getLoginUserId());
        if (companyList != null && companyList.size() > 0) {//存在管理权限
            List<String> companyIds = new ArrayList<>(companyList.size());//管理范围单位编号集合
            for (Dept company : companyList) {
                if (company != null) {
                    companyIds.add(company.getId());
                }
            }
            if (companyIds != null && companyIds.size() > 0) {
                logger.info("[查询公共的角色树] 当前用户[{}]拥有单位管理范围为:{},查询这些单位关联的共享角色", dept.getLoginUserId(), companyIds);

                List<Role> commonRoles2 = roleService.getParentOpenToDirectChildRoleList(companyIds);//直属单位共享给自己的角色
                if (commonRoles2 != null && commonRoles2.size() > 0) {
                    Dept commonNode = new Dept();
                    commonNode.setName("直属上级的公开角色");
                    commonNode.setRoleList(commonRoles2);
                    list.add(commonNode);
                }

                List<Role> commonRoles3 = roleService.getAllParentOpenToAllChildRoleList(companyIds);//所有上级单位共享给自己的角色
                if (commonRoles3 != null && commonRoles3.size() > 0) {
                    Dept commonNode = new Dept();
                    commonNode.setName("所有上级的公开角色");
                    commonNode.setRoleList(commonRoles3);
                    list.add(commonNode);
                }

                List<Role> commonRoles = roleDeptService.getRoleListByCompanyIds(companyIds);
                if (commonRoles != null && commonRoles.size() > 0) {
                    Dept commonNode = new Dept();
                    commonNode.setName("其他可用角色");
                    commonNode.setRoleList(commonRoles);
                    list.add(commonNode);
                }
            }

        }
        return list;
    }

    /**
     * 查询单位用户树
     *
     * @param dept 查询参数
     * @return 单位用户树
     */
    @Log("查询单位用户树")
    @Override
    public List<Dept> getCompanyUserTree(Dept dept) {
        //查询单位列表
        List<Dept> list = deptService.getListAsTree(dept);
        if (list == null || list.size() == 0){
            return null;
        }
        //查询用户列表
        User user = new User();
        AuthHelper.setAuthWhenEnableAuthIsNull(user);//启用数据权限
        List<User> userList = userService.getListAsTree(user);

        //将单位列表和用户列表关联起来
        if (userList != null && userList.size() > 0){
            //list转map,优化后续的查询性能
            Map<String, Dept> deptMap = new HashMap<String, Dept>(list.size());
            for (Dept dept1 : list){
                deptMap.put(dept1.getId(), dept1);
            }

            for (User user1 : userList){
                String companyId = user1.getCompanyId();//该用户所属的单位编号
                Dept dept1 = deptMap.get(companyId);//从map中找到对应的单位
                if (dept1 == null){
                    logger.warn("[查询单位用户树] 用户[{}]的所属单位[{}]在查询到的单位集合中匹配不到对应单位", user1.getId(), user1.getCompanyId());
                    continue;
                }
                if (dept1.getUserList() == null){
                    dept1.setUserList(new ArrayList<User>());
                }
                dept1.getUserList().add(user1);
            }
        }
        return list;
    }
}
